import { mapGetters } from "vuex";
import func from "@/util/func";
export default (app, option = {}) => {
  let mixins = {
    data () {
      return {
        options: option,
        firstLoad: true,
        selection: [],
        data: [],
        form: {},
        params: {},
        api: require(`@/api${option.name}`),
        loading: false,
        page: {
          pageSizes: [10, 20, 30, 40, 50, 100, 1500, 3000],
          pageSize: 20
        },
        search: {},
        isShowTenant: this.$store.getters.isShowTenantCode
      }
    },
    computed: {
      ...mapGetters(['userInfo', 'tenantCode']),
      option(){
        return require(`@/table${option.name}`).default(this)
      },
      bindVal () {
        return {
          ref: 'crud',
          option: this.option,
          data: this.data,
          tableLoading: this.loading
        }
      },
      ids () {
        let ids = [];
        this.selection.forEach(ele => {
          ids.push(ele[this.rowKey]);
        });
        return ids.join(",");
      },
      onEvent () {
        return {
          'before-open': this.beforeOpen,
          'selection-change': this.selectionChange,
          'on-load': this.getList,
          'row-save': this.rowSave,
          'row-update': this.rowUpdate,
          'row-del': this.rowDel,
          'refresh-change': this.refreshChange,
          'date-change': this.dateChange,
          'search-reset': this.searchReset,
          'search-change': this.searchChange
        }
      },
      rowKey () {
        return this.option.rowKey || option.rowKey || 'id'
      }
    },
    created () {
      if (option.onLoad === false) {
        this.firstLoad = option.onLoad
      }
    },
    methods: {
      beforeOpen (done, type) {
        if (["add"].includes(type)) {
          this.form.tenantCode = this.tenantCode;
        }
        done()
      },
      getList () {
        const callback = () => {
          this.loading = true;
          let pageParams = {};

          if (option.crudPage !== false){
            pageParams[option.pageSize || 'pageSize'] = this.page.pageSize
            pageParams[option.pageNum || 'pageNum'] = this.page.currentPage
          }
          let data = Object.assign(pageParams, this.params)

          this.data = [];
          this.api[this.options.list || 'list'](data).then(res => {
            this.loading = false;
            let data;
            if (option.res) {
              data = option.res(res.data);
            } else {
              data = res.data.data
            }
            this.page.total = Number(data[option.total || 'total']) || 0;
            const result = data[option.data || 'data'];
            this.data = result;
            if (this.listAfter) {
              this.listAfter(data)
            } else {
              this.$message.success('获取成功')
            }
          }).catch(()=>{
            this.loading = false;
          })
        }
        if (!this.firstLoad) {
          this.firstLoad = true
          return
        }
        if (this.listBefore) {
          this.listBefore(callback)
        }else {
          callback()
        }

      },
      rowSave (row, done, loading) {
        const callback = () => {
          delete this.form.params;
          this.api[option.add || 'add'](this.form).then((data) => {
            if (this.addAfter) {
              this.addAfter(row, done, data.data);
            } else {
              done();
              this.getList();
              this.$message.success('新增成功')
            }
          }).catch(() => {
            if (loading) {
              loading();
            }else{
              done();
            }
          })
        }
        if (this.addBefore) {
          this.addBefore(callback)
        }else{
          callback()
        }
      },
      rowUpdate (row, index, done, loading) {
        const callback = () => {
          delete this.form.params;
          delete this.form.createOrg;
          delete this.form.createUser;
          delete this.form.createTime;
          delete this.form.updateTime;
          delete this.form.updateUser;

          this.api[option.update || 'update'](row[this.rowKey], this.form, index).then(() => {
            if (this.updateAfter) {
              this.updateAfter(row, done)
            } else {
              done();
              this.getList();
              this.$message.success('更新成功')
            }
          }).catch(() => {
            loading()
          })
        }
        if (this.updateBefore) {
          this.updateBefore(row,loading,callback)
        } else {
          callback()
        }
      },
      rowDel (row, index, done) {
        const callback = () => {
          this.api[option.del || 'del'](row[this.rowKey], row, this.params).then(() => {
            if (this.delAfter) {
              this.delAfter(row, done);
            } else {
              this.getList();
              this.$message.success('删除成功')
            }
          })
        }
        if (this.delBefore) {
          this.delBefore(callback);
        } else {
          this.$confirm(`此操作将永久删除序号【${index+1}】的数据, 是否继续?`, '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            callback()
          })
        }
      },
      deletes () {

        if (this.ids.length <= 0){
          this.$message.warning("至少选中一条数据");
          return;
        }

        const callback = () => {
          this.$NProgress.start();
          this.api[option.del || 'del'](this.ids).then((res) => {
            this.$NProgress.done();
            res = res.data;
            if (res.status){
              if (this.delsAfter) {
                if (res.data){
                  this.ids = func.join(res.data);
                }
                this.delsAfter(this.ids)
              } else {
                this.getList();
                this.$message.success('删除成功')
              }
            }
          }).catch(() =>{
            this.$NProgress.done();
          })
        }
        if (this.delBefore) {
          this.delBefore(callback);
        } else {
          this.$confirm(`此操作将永久删除选中数据, 是否继续?`, '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            callback()
          })
        }
      },
      searchChange (params, done) {
        if (done) done();
        const dateSearchProp = this.option.dateSearchProp || 'createTime';
        const dateSearchProps = this.option.dateSearchProps || [dateSearchProp+'_datege',dateSearchProp+'_datele']
        if (this.validatenull(params)) {
          Object.keys(this.params).forEach(ele => {
            if (!dateSearchProps.includes(ele)) {
              delete this.params[ele]
            }
          })
        } else {
          const start = this.params[dateSearchProps[0]];
          const end = this.params[dateSearchProps[1]];
          this.params = params;
          if (!this.validatenull(start)){
            this.params[dateSearchProps[0]] = start;
          }
          if (!this.validatenull(end)){
            this.params[dateSearchProps[1]] = end;
          }
        }
        this.page.currentPage = 1;
        if (this.searchBefore){
          this.searchBefore();
        }
        this.getList();
      },
      searchReset(params, done){
        params = {};
        this.search = {};
        this.searchChange({}, done);
      },
      dateChange (date) {
        const dateSearchProp = this.option.dateSearchProp || 'createTime';
        const dateSearchProps = this.option.dateSearchProps || [dateSearchProp+'_datege',dateSearchProp+'_datele']
        // 默认是根据创建时间查询
        if (date.value) {
          this.params[dateSearchProps[0]] = date.value[0]
          this.params[dateSearchProps[1]] = date.value[1]
        } else {
          delete this.params[dateSearchProps[0]]
          delete this.params[dateSearchProps[1]]
        }

        this.page.currentPage = 1;
        this.getList();
      },
      selectionChange (list) {
        this.selection = list;
      },
      refreshChange () {
        this.getList();
      }
    }
  }
  app.mixins = app.mixins || [];
  app.mixins.push(mixins)
  return app;
}